package com.becca.cake.service.goods.impl;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.becca.cake.core.exception.ServiceException;
import com.becca.cake.core.freemarker.FreeMarkerHelp;
import com.becca.cake.core.qiniu.FileNameRuleHelp;
import com.becca.cake.core.qiniu.QiNiuGoodsPicTemplate;
import com.becca.cake.core.qiniu.bean.QiNiuResponse;
import com.becca.cake.dao.fixing.FixingDAO;
import com.becca.cake.dao.goods.GoodsDAO;
import com.becca.cake.dao.order.OrderDAO;
import com.becca.cake.dao.statistics.StatisticDAO;
import com.becca.cake.dao.users.UserManagerDAO;
import com.becca.cake.model.coupon.GoodsActivityModel;
import com.becca.cake.model.goods.GoodsDetailModel;
import com.becca.cake.model.goods.GoodsLableModel;
import com.becca.cake.model.goods.GoodsModel;
import com.becca.cake.model.goods.GoodsPictureModel;
import com.becca.cake.model.goods.GoodsPriceSizeModel;
import com.becca.cake.model.system.AdminDO;
import com.becca.cake.service.goods.IGoodsService;
import com.becca.cake.util.CodeUtil;
import com.becca.cake.util.JsonUtil;

/**
 * 商品管理service实现类
 * @copyright  尊星(上海)信息科技有限公司
 * @author yellow
 * @date 2016年5月18日 下午9:25:47
 */
@Service
public class GoodsServiceImpl implements IGoodsService {
    @Autowired
    private GoodsDAO       goodsDAO;

    @Autowired
    public OrderDAO        orderDAO;

    @Autowired
    private StatisticDAO   statisticDAO;

    @Autowired
    private UserManagerDAO userManagerDAO;

    @Autowired
    private FixingDAO      fixingDAO;

    @Override
    public List<GoodsModel> selectGoods(Map<String, Object> map) throws Exception {
        return this.goodsDAO.selectGoods(map);
    }

    @Override
    public Long selectGoodsCount(Map<String, Object> map) throws Exception {
        return this.goodsDAO.selectGoodsCount(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updGoodsStatusById(Integer goodsId, Integer goodsStatus, String trueName)
                                                                                         throws ServiceException {
        // 1.step 校验商品ID
        GoodsModel.validGoodsIdNull(goodsId);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("goodsId", goodsId);
        paramMap.put("goodsStatus", goodsStatus);
        paramMap.put("userName", trueName);
        GoodsModel goodsModel = goodsDAO.selectGoodsById(goodsId);
        // 2.step 校验商品对象是否存在
        if (goodsModel == null) {
            throw new ServiceException(GoodsModel.GOODS_NOT_EXISTS);
        }
        Long isGoodsStatusDown = goodsDAO.isGoodsStatusExist(paramMap);
        // 3.step 校验商品对象是否已下架
        if (isGoodsStatusDown != 0) {
            throw new ServiceException(GoodsModel.GOODS_STATUS_DOWN_EXIST);
        }
        this.goodsDAO.updGoodsStatusById(paramMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void insertOrUpdateGoods(GoodsModel goodsModel, List<MultipartFile> files,
                                    String freeMarketFoderPath, String fileTempPath, AdminDO adminDo)
                                                                                                     throws Exception {
        // step1: 数据校验
        GoodsModel.validateGoodsParam(files, goodsModel);
        // 2.step 上传商品图片
        for (MultipartFile multipartFile : files) {
            if (!multipartFile.isEmpty()) {
                //step3:重新生成图片文件名
                String fileName = FileNameRuleHelp.getGoodsPictureFileName() + "."
                                  + FilenameUtils.getExtension(multipartFile.getOriginalFilename());
                String filePath = fileTempPath + File.separator + fileName;
                File localFile = new File(filePath);
                multipartFile.transferTo(localFile);
                //step4:调用七牛上传图片
                QiNiuResponse response = QiNiuGoodsPicTemplate.uploadFile(localFile, fileName);
                if (response.isSuccess()) {
                    String goodsPicPath = QiNiuGoodsPicTemplate.getDownloadUrl(response.key);
                    if (StringUtils.isNotEmpty(goodsPicPath)
                        && "goodsBasePic_upload".equals(multipartFile.getName())) {//白底图
                        goodsModel.setGoodsBasePic(goodsPicPath);
                    } else if (StringUtils.isNotEmpty(goodsPicPath)
                               && "goodsPic_upload".equals(multipartFile.getName())) {
                        goodsModel.setGoodsPic(goodsPicPath);
                    }
                } else {
                    throw new ServiceException(GoodsPictureModel.PICTURE_UPDLOAD_FAILED);
                }
                //step5:删除本地图片
                if (localFile.isFile() && localFile.exists()) {
                    localFile.delete();
                }
            }
        }

        //step6:生成商品详情静态文件,并上传
        String goodsDescUrl = "";
        String filePostfix = UUID.randomUUID().toString() + ".html";
        //本地html保存路径
        String localHtmlPath = freeMarketFoderPath + File.separator + filePostfix;
        Map<String, Object> mapParam = new HashMap<String, Object>();
        mapParam.put("goodsDesc", goodsModel.getGoodsDescHtml());
        boolean flag = FreeMarkerHelp.makeHtml("goodsDetail.ftl", localHtmlPath, mapParam);
        if (flag) {//上传
            File localFile = new File(localHtmlPath);
            QiNiuResponse response = QiNiuGoodsPicTemplate.uploadFileInfo(localFile, filePostfix);
            if (!response.isSuccess()) {
                throw new ServiceException(GoodsModel.UPLOAD_FILE_FAILURE);
            }
            goodsDescUrl = QiNiuGoodsPicTemplate.getFileDownloadUrl(response.key);
        }

        //step7:添加或修改商品信息
        if (goodsModel.getId() == null) {//添加
            goodsModel.setGoodsType(GoodsModel.GOODS_TYPE_DEFALUT);
            goodsModel.setCreatedName(adminDo.getTrueName());
            this.goodsDAO.insertGoods(goodsModel);
            //step8:添加后设置商品编号
            Integer goodsId = goodsModel.getId();
            String goodsCode = CodeUtil.formatFixingCode("GD", goodsId);
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("goodsId", goodsId);
            map.put("goodsCode", goodsCode);
            this.goodsDAO.updGoodsCode(map);
            //step9:添加商品详情
            GoodsDetailModel goodsDetailModel = new GoodsDetailModel();
            goodsDetailModel.setGoodsId(goodsId);
            goodsDetailModel.setGoodsDescHtml(goodsModel.getGoodsDescHtml());
            goodsDetailModel.setGoodsDescUrl(goodsDescUrl);
            goodsDetailModel.setCreatedName(adminDo.getTrueName());
            this.goodsDAO.insertGoodsDetail(goodsDetailModel);
        } else {//修改
            goodsModel.setUpdatedName(adminDo.getTrueName());
            this.goodsDAO.updateGoods(goodsModel);
            //修改商品明细
            GoodsDetailModel goodsDetailModel = new GoodsDetailModel();
            goodsDetailModel.setGoodsId(goodsModel.getId());
            goodsDetailModel.setGoodsDescHtml(goodsModel.getGoodsDescHtml());
            goodsDetailModel.setGoodsDescUrl(goodsDescUrl);
            goodsDetailModel.setUpdatedName(adminDo.getTrueName());
            this.goodsDAO.updateGoodsDetail(goodsDetailModel);
        }
    }

    @Override
    public GoodsModel selectGoodsById(Integer goodsId) throws ServiceException {
        return this.goodsDAO.selectGoodsById(goodsId);
    }

    @Override
    public List<GoodsPriceSizeModel> queryGoodsPriceSizeByGoodsId(Map<String, Object> map)
                                                                                          throws DataAccessException {
        return this.goodsDAO.queryGoodsPriceSizeByGoodsId(map);
    }

    @Override
    public Long queryGoodsPriceSizeCount(Map<String, Object> map) throws ServiceException {
        return this.goodsDAO.queryGoodsPriceSizeCount(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void addOrUpdGoodsPriceSize(GoodsPriceSizeModel goodsPriceSizeModel, String trueName)
                                                                                                throws ServiceException {
        // 1.step 校验
        GoodsPriceSizeModel.validSaveGoodsPriceSize(goodsPriceSizeModel);
        if (goodsPriceSizeModel.getId() == null) {
            goodsPriceSizeModel.setIsDelete(GoodsPriceSizeModel.IS_NOT_DELETE);
            ;
            Long isExistGPS = this.goodsDAO.isExistGPS(goodsPriceSizeModel);
            // 2.step 判断是否存在
            if (isExistGPS != 0) {
                throw new ServiceException(GoodsPriceSizeModel.GOODSPRICE_IS_EXIST);
            }
            goodsPriceSizeModel.setCreatedName(trueName);
            goodsPriceSizeModel.setIsDelete(GoodsModel.GOODSPRICESIZE_ISNOT_DELETE);
            this.goodsDAO.insertGoodsPriceSize(goodsPriceSizeModel);
            // 3.step 设置商品规格编码
            String goodsCode = goodsPriceSizeModel.getGoodsCode();
            Integer id = goodsPriceSizeModel.getId();
            String goodsStandardCode = CodeUtil.formatgoodsPriceSize(goodsCode, id);
            goodsPriceSizeModel.setGoodsStandardCode(goodsStandardCode);

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("goodsStandardCode", goodsStandardCode);
            map.put("id", id);
            this.goodsDAO.updGoodsStandardCode(map);
        } else {
            // 判断是否已删除
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", goodsPriceSizeModel.getId());
            map.put("isDelete", GoodsModel.GOODSPRICESIZE_IS_DELETE);
            Long isDeleteGPS = this.goodsDAO.isDeleteGPS(map);
            if (isDeleteGPS != 0) {
                throw new ServiceException(GoodsPriceSizeModel.GOODSPRICE_IS_NOT_EXIST);
            }

            // 判断是否存在
            Long isExistGPS = this.goodsDAO.isExistGPS(goodsPriceSizeModel);
            if (isExistGPS != 0) {
                throw new ServiceException(GoodsPriceSizeModel.GOODSPRICE_IS_EXIST);
            }
            goodsPriceSizeModel.setUpdatedName(trueName);

            this.goodsDAO.updateGoodsPriceSize(goodsPriceSizeModel);
        }
    }

    @Override
    public GoodsPriceSizeModel selectGoodsPriceSizeModelById(Integer id) throws ServiceException {
        // 1.step 校验商品尺寸ID
        GoodsPriceSizeModel.validGoodsPriceSizeId(id);
        return this.goodsDAO.selectGoodsPriceSizeModelById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updIsDelete(Integer id, Integer isDelete, String trueName) throws ServiceException {
        // 1.step 校验商品尺寸ID
        GoodsPriceSizeModel.validGoodsPriceSizeId(id);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("id", id);
        paramMap.put("isDelete", isDelete);
        paramMap.put("userName", trueName);
        Long isDeleteGPS = this.goodsDAO.isDeleteGPS(paramMap);
        if (isDeleteGPS != 0) {
            throw new ServiceException(GoodsPriceSizeModel.GOODSPRICE_IS_NOT_EXIST);
        }
        this.goodsDAO.updIsDelete(paramMap);
    }

    @Override
    public Long queryGoodsPicCount(Map<String, Object> map) throws ServiceException {
        return this.goodsDAO.queryGoodsPicCount(map);
    }

    @Override
    public GoodsPictureModel selectGoodsPicById(Integer id) throws ServiceException {
        GoodsPictureModel.validGoodsPictureIsNull(id);
        return this.goodsDAO.selectGoodsPicById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updGoodsPicIsDelete(Integer id, Integer isDelete, String trueName)
                                                                                  throws ServiceException {
        GoodsPictureModel.validGoodsPictureIsNull(id);
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("id", id);
        paramMap.put("isDelete", isDelete);
        paramMap.put("userName", trueName);
        Long isDeleteGoodsPic = this.goodsDAO.isDeleteGoodsPic(paramMap);
        if (isDeleteGoodsPic != 0) {
            throw new ServiceException(GoodsPictureModel.GOODS_PICTURE_DELETE);
        }
        this.goodsDAO.updGoodsPicIsDelete(paramMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void insertOrUpdateGoodsPic(GoodsPictureModel goodsPictureModel, MultipartFile files,
                                       String fileTempPath, AdminDO adminDo) throws Exception {
        goodsPictureModel.setIsDelete(GoodsPictureModel.PIC_IS_NOT_DELETE);
        // 1.step 商品图片数据校验
        GoodsPictureModel.validAddOrUpdGoodsPic(goodsPictureModel, files);

        // 3.step 上传图片
        String goodsPicPath = "";
        if (!files.isEmpty()) {
            //step3:重新生成图片文件名
            String fileName = FileNameRuleHelp.getGoodsPictureFileName() + "."
                              + FilenameUtils.getExtension(files.getOriginalFilename());
            String filePath = fileTempPath + File.separator + fileName;
            File localFile = new File(filePath);
            files.transferTo(localFile);
            //step4:调用七牛上传图片
            QiNiuResponse response = QiNiuGoodsPicTemplate.uploadFile(localFile, fileName);
            if (response.isSuccess()) {
                goodsPicPath = QiNiuGoodsPicTemplate.getDownloadUrl(response.key);
            } else {
                throw new ServiceException("图片上传失败!");
            }
            // step5:删除本地图片
            localFile.delete();
        }
        if (StringUtils.isNotEmpty(goodsPicPath)) {
            goodsPictureModel.setPicPath(goodsPicPath);
        }
        // step6:添加或修商品图片
        if (goodsPictureModel.getId() == null) {// 新增
            goodsPictureModel.setCreatedName(adminDo.getTrueName());
            this.goodsDAO.insertGoodsPic(goodsPictureModel);
        } else {// 修改
            this.goodsDAO.updateGoodsPic(goodsPictureModel);
        }
    }

    @Override
    public List<GoodsPictureModel> queryGoodsPics(Map<String, Object> map) throws Exception {
        return this.goodsDAO.queryGoodsPics(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String uploadPictureFile(MultipartFile files, String fileTempPath) throws Exception {
        //step1:数据校验
        if (files == null || files.isEmpty()) {
            throw new ServiceException("请上传图片文件!");
        }
        //step2:上传图片
        String picPath = "";
        //step3:重新生成图片文件名
        String fileName = FileNameRuleHelp.getGoodsPictureFileName() + "."
                          + FilenameUtils.getExtension(files.getOriginalFilename());
        String filePath = fileTempPath + File.separator + fileName;
        File localFile = new File(filePath);
        files.transferTo(localFile);
        //step4:调用七牛上传图片
        QiNiuResponse response = QiNiuGoodsPicTemplate.uploadFile(localFile, fileName);
        if (response.isSuccess()) {
            picPath = QiNiuGoodsPicTemplate.getDownloadUrl(response.key);
        } else {
            throw new ServiceException("图片上传失败!");
        }
        //step5:删除本地图片
        localFile.delete();
        if (StringUtils.isEmpty(picPath)) {
            throw new ServiceException("图片文件上传失败!");
        }
        return picPath;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateGoodsPicOrders(String jsonList) throws ServiceException {
        List<GoodsPictureModel> list = JsonUtil.returnObjectList(jsonList, GoodsPictureModel.class);
        GoodsPictureModel.validGoodsPicOrders(list);
        this.goodsDAO.updateGoodsPicOrders(list);
    }

    @Override
    public List<GoodsActivityModel> selectGoodsActivity(Map<String, Object> map)
                                                                                throws ServiceException {
        return this.goodsDAO.selectGoodsActivity(map);
    }

    @Override
    public Long selectGoodsActivityCount(Map<String, Object> map) throws ServiceException {
        return this.goodsDAO.selectGoodsActivityCount(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void insertOrUpdateGoodsActivity(GoodsActivityModel goodsActivityModel, String trueName)
                                                                                                   throws ServiceException {

        // 1.step 校验是否为空
        GoodsActivityModel.validAddOrUpdGoodsActivity(goodsActivityModel);
        // 2.step 根据id判断添加或修改
        if (goodsActivityModel.getId() == null) {
            // 添加
            goodsActivityModel.setCreatedName(trueName);
            this.goodsDAO.insertGoodsActivity(goodsActivityModel);
        } else {
            // 修改
            goodsActivityModel.setUpdatedName(trueName);
            this.goodsDAO.updateGoodsActivity(goodsActivityModel);
        }
    }

    @Override
    public GoodsActivityModel selectGoodsActivityUpdById(Integer id) throws ServiceException {
        GoodsActivityModel.validGoodsActivityIdIsNull(id);
        return this.goodsDAO.selectGoodsActivityUpdById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateGoodsOrder(String jsonList, String userName) throws ServiceException {
        //step1:请求参数
        List<GoodsModel> list = JsonUtil.returnObjectList(jsonList, GoodsModel.class);
        GoodsModel.validGoodsOrder(list);
        //step2:封装请求参数
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("goodsList", list);
        paramMap.put("userName", userName);
        this.goodsDAO.updateGoodsOrder(paramMap);
    }

    @Override
    public List<GoodsLableModel> selectGoodsLable(Map<String, Object> map) throws ServiceException {
        return this.goodsDAO.selectGoodsLable(map);
    }

    @Override
    public Long selectGoodsLableCount(Map<String, Object> map) throws ServiceException {
        return this.goodsDAO.selectGoodsLableCount(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void addOrUpdateGoodsLable(GoodsLableModel goodsLableModel, AdminDO adminDo)
                                                                                       throws ServiceException {
        if (goodsLableModel.getId() == null) {//添加
            goodsLableModel.setCreatedName(adminDo.getTrueName());
            this.goodsDAO.insertGoodsLable(goodsLableModel);
        } else {
            goodsLableModel.setUpdatedName(adminDo.getTrueName());
            this.goodsDAO.updateGoodsLable(goodsLableModel);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void deleteGoodsLableById(Integer id) throws ServiceException {
        this.goodsDAO.deleteGoodsLableById(id);
    }

    @Override
    public GoodsLableModel selectGoodsLableById(Integer id) throws ServiceException {
        return this.goodsDAO.selectGoodsLableById(id);
    }

}